home *** CD-ROM | disk | FTP | other *** search
/ Light ROM 1 / LIGHT-ROM 1 (Amiga Library Services)(1994).iso / ffdisks / d939.lha / ExtraCmds / source_etc.lha / src / Unique.c < prev    next >
C/C++ Source or Header  |  1993-10-22  |  5KB  |  234 lines

  1. /*
  2.  *  Unique - Report repeated lines in input.
  3.  *  Copyright (C) 1989, 1992, 1993 Torsten Poulin
  4.  *
  5.  *  This program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2 of the License, or
  8.  *  (at your option) any later version.
  9.  *
  10.  *  This program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *  GNU General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with this program; if not, write to the Free Software
  17.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  *  The author can be contacted by s-mail at
  20.  *    Torsten Poulin
  21.  *    Banebrinken 99, 2, 77
  22.  *    DK-2400 Copenhagen NV
  23.  *    DENMARK
  24.  *
  25.  * $Id: Unique.c,v 37.7 93/06/20 17:14:14 Torsten Rel $
  26.  * $Log:    Unique.c,v $
  27.  * Revision 37.7  93/06/20  17:14:14  Torsten
  28.  * SysBase removed.
  29.  * Removed unsupported items from the template so as not
  30.  * to confuse "lusers".
  31.  * 
  32.  * Revision 37.6  93/03/01  12:31:13  Torsten
  33.  * Changed all occurrences of "struct DosBase *" to "struct DosLibrary *"
  34.  * 
  35.  * Revision 37.5  93/02/18  15:35:21  Torsten
  36.  * Replaced explicit Stricmp() pragma and prototype with the
  37.  * relevant include files.
  38.  * 
  39.  * Revision 37.4  93/02/14  10:49:48  Torsten
  40.  * Replaced exec.library/SetSignal() with dos.library/CheckSignal().
  41.  * Fixed "line repeated more than once" bug.
  42.  * 
  43.  */
  44.  
  45. #include <exec/types.h>
  46. #include <exec/memory.h>
  47. #include <dos/dos.h>
  48. #include <dos/dosasl.h>
  49. #include <clib/dos_protos.h>
  50. #include <clib/exec_protos.h>
  51. #include <clib/utility_protos.h>
  52. #include <stdio.h>
  53. #include <string.h>
  54. #include "unique_rev.h"
  55.  
  56. #ifdef __SASC
  57. #include <pragmas/dos_pragmas.h>
  58. #include <pragmas/exec_pragmas.h>
  59. #include <pragmas/utility_pragmas.h>
  60. #endif
  61.  
  62. #define PROGNAME "Unique"
  63. #define MAXLINE (512+1)
  64. #define MAXNAME 50
  65. #define TEMPLATE "FROM,TO,REPEATED/S,UNIQUE=ONCE/S,COUNT/S"
  66.  
  67. #define OPT_FROM   0
  68. #define OPT_TO     1
  69. #define OPT_REPEAT 2
  70. #define OPT_UNIQUE 3
  71. #define OPT_COUNT  4
  72.  
  73. char const versionID[] = VERSTAG;
  74. char const copyright[] = "$COPYRIGHT:© 1989,1992,1993 Torsten Poulin$";
  75.  
  76. static BOOL ioerr(struct DosLibrary *DOSBase);
  77. static LONG unique(struct DosLibrary *DOSBase,
  78.                    struct Library *UtilityBase, BPTR in, BPTR out,
  79.                    BOOL rflag, BOOL uflag, BOOL cflag);
  80.  
  81. LONG entrypoint(VOID)
  82. {
  83.   BPTR in, out;
  84.   ULONG err;
  85.   LONG rc = RETURN_OK;
  86.     
  87.   struct DosLibrary *DOSBase;
  88.   struct Library *UtilityBase;
  89.   struct RDArgs  *args;
  90.   LONG           arg[5];
  91.         
  92.   if (!(DOSBase = (struct DosLibrary *) OpenLibrary("dos.library", 37L)))
  93.   {
  94.     rc = RETURN_FAIL;
  95.     goto noDOS;
  96.   }
  97.   if (!(UtilityBase = OpenLibrary("utility.library", 37L)))
  98.   {
  99.     rc = RETURN_FAIL;
  100.     goto noUtility;
  101.   }
  102.     
  103.   arg[OPT_FROM] = arg[OPT_TO] = 
  104.     arg[OPT_REPEAT] = arg[OPT_UNIQUE] = arg[OPT_COUNT] = 0L;
  105.     
  106.   if (args = ReadArgs(TEMPLATE, arg, NULL))
  107.   {
  108.     if (arg[OPT_FROM])
  109.     {
  110.       if (!(in = Open((UBYTE *) arg[OPT_FROM], MODE_OLDFILE)))
  111.       {
  112.     err = IoErr();
  113.     PrintFault(err, (UBYTE *) arg[OPT_FROM]);
  114.     rc = RETURN_ERROR;
  115.     goto errExit;
  116.       }
  117.     }
  118.     else
  119.       in = Input();
  120.  
  121.     if (arg[OPT_TO])
  122.     {
  123.       if (!(out = Open((UBYTE *) arg[OPT_TO], MODE_NEWFILE)))
  124.       {
  125.     err = IoErr();
  126.     PrintFault(err, (UBYTE *) arg[OPT_TO]);
  127.     rc = RETURN_ERROR;
  128.     goto errExit;
  129.       }
  130.     }
  131.     else
  132.       out = Output();
  133.         
  134.     rc = unique(DOSBase, UtilityBase, in, out,
  135.         (BOOL) arg[OPT_REPEAT],
  136.         (BOOL) arg[OPT_UNIQUE],
  137.         (BOOL) arg[OPT_COUNT]);
  138.  
  139.     if (arg[OPT_FROM])
  140.       Close(in);
  141.     if (arg[OPT_TO])
  142.       Close(out);
  143.  
  144.     FreeArgs(args);
  145.   }
  146.   else
  147.   {
  148.     LONG err = IoErr();
  149.     PrintFault(err, PROGNAME);
  150.     rc = RETURN_ERROR;
  151.   }
  152.     
  153.  errExit:
  154.   CloseLibrary(UtilityBase);
  155.  noUtility:
  156.   CloseLibrary((struct Library *) DOSBase);
  157.  noDOS:
  158.   return rc;
  159. }
  160.  
  161.  
  162. static LONG unique(struct DosLibrary *DOSBase,
  163.                    struct Library *UtilityBase, BPTR in, BPTR out,
  164.                    BOOL rflag, BOOL uflag, BOOL cflag)
  165. {
  166.   ULONG count;
  167.   UBYTE prevline[MAXLINE];
  168.   UBYTE nextline[MAXLINE];
  169.   UBYTE *temp;
  170.   UBYTE *prev = prevline;
  171.   UBYTE *next = nextline;
  172.     
  173.   if (rflag && uflag)
  174.     rflag = uflag = FALSE;
  175.  
  176.   count = 1;
  177.   if (FGets(in, prev, MAXLINE) == NULL)
  178.   {
  179.     if (ioerr(DOSBase))
  180.       return RETURN_FAIL;
  181.   }
  182.   else
  183.   {
  184.     while (FGets(in, next, MAXLINE) != NULL)
  185.     {
  186.  
  187.       if (Stricmp(prev, next) == 0)
  188.     ++count;
  189.       else if ((!rflag && !uflag) ||
  190.            (count >= 2 && !uflag) ||
  191.            (count == 1 && uflag))
  192.       {
  193.     if (cflag)
  194.       VFPrintf(out, "%10lu ", (LONG *) &count);
  195.     FPuts(out, prev);
  196.     count = 1;
  197.       }
  198.       else
  199.     count = 1;
  200.       temp = prev;
  201.       prev = next;
  202.       next = temp;
  203.  
  204.       if (CheckSignal(SIGBREAKF_CTRL_C))
  205.       {
  206.     PrintFault(ERROR_BREAK, NULL);
  207.     return RETURN_WARN;
  208.       }
  209.     }
  210.     if (ioerr(DOSBase))
  211.       return RETURN_FAIL;
  212.  
  213.     if ((!rflag && !uflag) || (count >= 2 && !uflag)
  214.     || (count == 1 && uflag))
  215.     {
  216.       if (cflag)
  217.     VFPrintf(out, "%10lu ", (LONG *) &count);
  218.       FPuts(out, prev);
  219.     }
  220.   }
  221.   return RETURN_OK;
  222. }
  223.  
  224.  
  225. static BOOL ioerr(struct DosLibrary *DOSBase)
  226. {
  227.     LONG err;
  228.     
  229.     if (!(err = IoErr()))
  230.         return FALSE;
  231.     PrintFault(err, PROGNAME);
  232.     return TRUE;
  233. }
  234.